package filehandler

import (
	"bytes"
	"context"
	"fmt"
	"github.com/cloudwego/hertz-examples/bizdemo/hertz_gorm/biz/repo/cloudapi"
	"github.com/cloudwego/hertz/pkg/common/hlog"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strconv"
	"time"
)

type FileFormat string

const (
	FileFormatDocx FileFormat = `docx`
	FileFormatDoc  FileFormat = "doc"
	FileFormatXls  FileFormat = "xls"
	FileFormatXlsx FileFormat = "xlsx"
	_FileFormatPpt FileFormat = "ppt"
	FileFormatPptx FileFormat = "pptx"
	FileFormatOdt  FileFormat = "odt"
	FileFormatOds  FileFormat = "ods"
	FileFormatOdp  FileFormat = "odp"
	FileFormatOfd  FileFormat = "ofd"
	FileFormatTxt  FileFormat = "txt"
	FileFormatHtml FileFormat = "html"
	FileFormatPdf  FileFormat = "pdf"
)

// ConvertFile 使用LibreOffice转换文件格式
// 输入文件: inputPath - 原始文件路径
// 输出目录: outputDir - 生成文件的存放目录
// 目标格式: targetFormat - 要转换的格式（如pdf, docx等）
// 超时时间: timeoutSec - 最大允许执行时间（秒）
func ConvertFile(ctx context.Context, inputPath, outputDir string, targetFormat FileFormat, timeoutSec int) (string, error) {
	// 参数校验
	if _, err := os.Stat(inputPath); os.IsNotExist(err) {
		return "", fmt.Errorf("输入文件不存在: %s", inputPath)
	}

	if _, err := os.Stat(outputDir); os.IsNotExist(err) {
		return "", fmt.Errorf("输出目录不存在: %s", outputDir)
	}

	// 准备转换命令
	ctx, cancel := context.WithTimeout(ctx, time.Duration(timeoutSec)*time.Second)
	defer cancel()
	// soffice --infilter="writer_pdf_import" --convert-to docx ./testcase.pdf --outdir ./
	// 示例命令：soffice --headless /output/path /input/file.docx
	cmd := exec.CommandContext(ctx,
		"sh", "-c",
		fmt.Sprintf(`soffice --infilter="%s" --convert-to %s %s --outdir %s`,
			"writer_pdf_import",
			targetFormat,
			strconv.Quote(inputPath),
			strconv.Quote(outputDir),
		))

	// 执行并捕获输出
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	err := cmd.Run()
	if err != nil || stderr.String() != "" {
		return "", fmt.Errorf("%s转换失败: %w\n输出日志: %s", cmd.String(), err, stderr.String())
	}

	// 验证输出文件
	outputFile := filepath.Join(outputDir,
		filepath.Base(inputPath[:len(inputPath)-len(filepath.Ext(inputPath))])+"."+string(targetFormat))

	if _, err := os.Stat(outputFile); os.IsNotExist(err) {
		return "", fmt.Errorf("%s 未检测到输出文件 %s 错误原因: %s", cmd.String(), outputFile, stdout.String())
	}
	hlog.CtxInfof(ctx, "任务执行成功：%s", stdout.String())

	return outputFile, nil
}

// 使用示例：
// outputPath, err := ConvertFile(context.Background(),
//     "/tmp/input.docx",
//     "/tmp/output",
//     "pdf",
//     30) // 30秒超时

func TestLibreoffice() {
	fmt.Println("测试libreoffice....")
	fmt.Println("下载测试文件....")
	// 指定要检查的文件夹路径
	tmpPath := "/home/ubuntu/file/tmp/"

	// 检查文件夹是否存在
	if _, err := os.Stat(tmpPath); os.IsNotExist(err) {
		// 如果文件夹不存在，则创建它
		err := os.MkdirAll(tmpPath, 0755)
		if err != nil {
			fmt.Printf("Error creating folder: %v\n", err)
			return
		}
		fmt.Printf("Folder '%s' created.\n", tmpPath)
	} else {
		fmt.Printf("Folder '%s' already exists.\n", tmpPath)
	}
	if err := cloudapi.NewCosProxy().DownloadFile(context.Background(), "tmp/testcase.pdf", path.Join(tmpPath, "testcase.pdf")); err != nil {
		fmt.Printf("Error downloading file: %v\n", err)
	}
	fmt.Println("转换文件格式....")
	outputPath, err := ConvertFile(context.Background(),
		path.Join(tmpPath, "testcase.pdf"),
		tmpPath, FileFormatDocx, 30)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("拷贝文件到cos存储桶", outputPath)
		key, err := cloudapi.NewCosProxy().UpLoadFile(context.Background(), "tmp/testcase.docx", outputPath)
		// 执行并捕获输出
		if err != nil {
			fmt.Println(err)
		} else {
			fmt.Println("拷贝成功", key)
		}
	}
}
